package com.ecr.hub.database.dao.impl;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.stereotype.Repository;

import com.ecr.hub.database.dao.IDaoReporting;
import com.ecr.hub.model.enumeration.HubSillonStatus;
import com.ecr.hub.model.enumeration.HubWagonStatus;

@Repository("daoReporting")
public class DaoReportingImpl implements IDaoReporting {

	// Requête pour les statistiques (Temps de rotation pour chaque wagon).
	private static final String REQ_REPORT_ROTATE_TRAFFIC = "SELECT * FROM (SELECT traffic.wagon_id, wagon.ext_id, "
			+ " MIN(traffic.date_update) AS date_update, traffic.status_id, traffic.lading "
			+ " FROM hub_histo_traffic AS traffic, hub_wagon AS wagon WHERE traffic.status_id="
			+ HubWagonStatus.WAGON_ARRIVED.getValue()
			+ " AND traffic.wagon_id = wagon.id "
			+ " AND (traffic.date_update >=? OR traffic.date_update) <=? "
			+ " GROUP BY traffic.wagon_id UNION SELECT traffic.wagon_id, "
			+ " wagon.ext_id, traffic.date_update, traffic.status_id, "
			+ " traffic.lading FROM hub_histo_traffic AS traffic, hub_wagon AS wagon WHERE traffic.status_id="
			+ HubWagonStatus.WAGON_DEPARTURE_COMPLETED.getValue()
			+ " AND traffic.wagon_id = wagon.id"
			+ " AND (traffic.date_update >=? OR traffic.date_update <=?)) "
			+ " AS report ORDER BY report.wagon_id, " + "report.status_id ASC;";

	// Requête pour les statistiques (écart de temps dates / heures des
	// sillons).
	private static final String REQ_REPORT_DELTA_SILLON = "SELECT sillon.ext_id, sillon.type, sillon.tcms_train_id, "
			+ "sillon.movement_date, sillon.movement_time, sillon.real_movement_date, "
			+ " sillon.real_movement_time, sillon.lading  FROM hub_sillon As sillon WHERE sillon.movement_date >= ?"
			+ "AND sillon.movement_date <= ? AND (sillon.status_id="
			+ HubSillonStatus.ARRIVAL_COMPLETED.getValue()
			+ " OR sillon.status_id="
			+ HubSillonStatus.DEPARTURE_COMPLETED.getValue()
			+ ") UNION SELECT sillon.ext_id, sillon.type, sillon.tcms_train_id, sillon.movement_date, "
			+ "sillon.movement_time, sillon.real_movement_date, sillon.real_movement_time, sillon.lading  "
			+ "FROM hub_histo_sillon As sillon WHERE sillon.movement_date >= ? "
			+ "AND sillon.movement_date <= ?";

	// Requête pour les statistiques (Nombre de wagon par voie à chaque
	// mouvement)
	private static final String REQ_REPORT_COUNT_WAGON_RAIL = "SELECT count(traffic.wagon_id), date_update, rail.number, rail.destination_label "
			+ ", bundle.label FROM hub_histo_traffic AS traffic, hub_rail AS rail, hub_bundle_type AS bundle WHERE rail.id = "
			+ "traffic.pos_rail_id AND rail.bundle_type_id = bundle.id  AND (date_update >= ? OR date_update <= ?) "
			+ "GROUP BY traffic.num_lot, traffic.pos_rail_id;";

	@Autowired
	JdbcTemplate jdbcTemplate;

	/**
	 * Récupération du taux de rotation des wagons (entrée / sorties) pour le
	 * hub. Il faudrait arriver à optimiser la requête pour qu'elle ne renvoi
	 * que les lignes dont les wagons sont effectivement sortis du hub....
	 */
	@Override
	public SqlRowSet reportTrafficRotation(Date date, Date dateEnd)
			throws DataAccessException {

		SqlRowSet rowSets = jdbcTemplate.queryForRowSet(
				REQ_REPORT_ROTATE_TRAFFIC, new Object[] { date, dateEnd, date,
						dateEnd });
		return rowSets;
	}

	/**
	 * Récupération de l'écart entre les heures théorique et réelles des sillons
	 * (arrivées / départs). Comme les sillons sont conservés 3 semaines dans la
	 * table de travail, on fait la requête dans la table d'historisation mais
	 * aussi dans la table de travail.
	 */
	@Override
	public SqlRowSet reportDeltaSillon(Date date, Date dateEnd)
			throws DataAccessException {

		SqlRowSet rowSets = jdbcTemplate.queryForRowSet(
				REQ_REPORT_DELTA_SILLON, new Object[] { date, dateEnd, date,
						dateEnd });
		return rowSets;
	}

	/**
	 * Récupération du nombre de wagons pour chaque voie On récupère le nombre
	 * de wagons à chaque lot (chaque rotation) dans la table hub_histo_traffic.
	 */
	@Override
	public SqlRowSet reportCountRailWagon(Date date, Date dateEnd)
			throws DataAccessException {

		SqlRowSet rowSets = jdbcTemplate.queryForRowSet(
				REQ_REPORT_COUNT_WAGON_RAIL, new Object[] { date, dateEnd });
		return rowSets;
	}
}
